package com.uuah.server.config.spring.handlers;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

import com.uuah.server.config.spring.factories.UuahEndpointFactoryBean;
import com.uuah.server.config.spring.parsers.IUuahDefinitionParser;
import com.uuah.server.config.spring.parsers.IUuahDefinitionParserConfiguration;
import com.uuah.server.config.spring.parsers.PostProcessor;
import com.uuah.server.config.spring.parsers.PreProcessor;
import com.uuah.server.config.spring.parsers.assembly.configuration.IValueMap;
import com.uuah.server.config.spring.parsers.generic.UuahOrphanDefinitionParser;
import com.uuah.server.config.spring.parsers.specific.endpoint.TransportEndpointDefinitionParser;
import com.uuah.server.config.spring.parsers.specific.endpoint.support.AddressedEndpointDefinitionParser;

/**
 *
 * TODO comment ...
 *
 * <p>update record:updator，update time，update content and version</p>
 * @author <a href="jonny_quan@hotmail.com">jonny</a>
 * @date 2009 2009-3-27 上午10:04:25
 * @version 1.0.0
 */
public abstract class AbstractUuahNamespaceHandler extends
		NamespaceHandlerSupport {

	protected final void registerIgnoredElement(String name) {
		registerBeanDefinitionParser(name, new IgnoredDefinitionParser());
	}

	protected IUuahDefinitionParserConfiguration registerConnectorDefinitionParser(
			Class connectorClass) {
		return registerConnectorDefinitionParser(new UuahOrphanDefinitionParser(
				connectorClass, true));
	}

	protected IUuahDefinitionParserConfiguration registerConnectorDefinitionParser(
			IUuahDefinitionParser parser) {
		registerBeanDefinitionParser("connector", parser);
		return parser;
	}

	protected IUuahDefinitionParserConfiguration registerUuahBeanDefinitionParser(
			String name, IUuahDefinitionParser parser) {
		registerBeanDefinitionParser(name, parser);
		return parser;
	}

	protected IUuahDefinitionParserConfiguration registerStandardTransportEndpoints(
			String protocol, String[] requiredAttributes) {
		return new RegisteredMdps(protocol, AddressedEndpointDefinitionParser.PROTOCOL, requiredAttributes);
	}

	protected IUuahDefinitionParserConfiguration registerMetaTransportEndpoints(
			String protocol) {
		return new RegisteredMdps(protocol, AddressedEndpointDefinitionParser.META, new String[] {});
	}

	private class IgnoredDefinitionParser implements BeanDefinitionParser {
		public BeanDefinition parse(Element element, ParserContext parserContext) {
			return null;
		}
	}

	protected Class getRequestEndpointFactoryBeanClass() {
		return UuahEndpointFactoryBean.class;
	}

	private class RegisteredMdps implements IUuahDefinitionParserConfiguration {

		private Set bdps = new HashSet();

		private RegisteredMdps(String protocol, boolean isMeta,
				String[] requiredAttributes) {
			registerBeanDefinitionParser("request-endpoint",
					add(new TransportEndpointDefinitionParser(protocol, isMeta,
							AbstractUuahNamespaceHandler.this
									.getRequestEndpointFactoryBeanClass(),
							requiredAttributes, new String[] {})));
		}

		private IUuahDefinitionParser add(IUuahDefinitionParser bdp) {
			bdps.add(bdp);
			return bdp;
		}

		public IUuahDefinitionParserConfiguration registerPreProcessor(
				PreProcessor preProcessor) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.registerPreProcessor(preProcessor);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration registerPostProcessor(
				PostProcessor postProcessor) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.registerPostProcessor(postProcessor);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addReference(
				String propertyName) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.addReference(propertyName);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addMapping(
				String propertyName, Map mappings) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next()).addMapping(
						propertyName, mappings);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addMapping(
				String propertyName, String mappings) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next()).addMapping(
						propertyName, mappings);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addMapping(
				String propertyName, IValueMap mappings) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next()).addMapping(
						propertyName, mappings);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addAlias(String alias,
				String propertyName) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next()).addAlias(
						alias, propertyName);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addCollection(
				String propertyName) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.addCollection(propertyName);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addIgnored(String propertyName) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.addIgnored(propertyName);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration removeIgnored(
				String propertyName) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.removeIgnored(propertyName);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration setIgnoredDefault(
				boolean ignoreAll) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.setIgnoredDefault(ignoreAll);
			}
			return this;
		}

		public IUuahDefinitionParserConfiguration addBeanFlag(String flag) {
			for (Iterator bdp = bdps.iterator(); bdp.hasNext();) {
				((IUuahDefinitionParserConfiguration) bdp.next())
						.addBeanFlag(flag);
			}
			return this;
		}

	}

}
